<template>
  <div class="setting-container">
    <div class="app-container">
      <!-- el-card 包裹有盒子阴影 -->
      <el-card>
        <el-tabs v-model="activeName">
          <el-tab-pane label="角色管理" name="role">
            <!-- 新增角色按钮 -->
            <el-button
              v-if="$checkPermission('point-add')"
              type="primary"
              size="small"
              @click="showAddDialog = true"
            >
              <el-icon name="plus" />
              新增角色
            </el-button>
            <!--
              角色列表
              table组件中
              data:数据源（对象数组）
              el-table-column:
              prop:渲染对象指定key对应的值
              label:渲染表头的名字
              width:单元格的宽度
            -->
            <el-table :data="roleList" border style="width: 100%">
              <el-table-column
                type="index"
                :index="handleIndex"
                prop="date"
                label="序号"
                width="180"
              ></el-table-column>
              <el-table-column prop="name" label="名称" width="180"></el-table-column>
              <el-table-column prop="description" label="描述"></el-table-column>
              <el-table-column label="操作">
                <!-- 具名插槽老式写法 -->
                <!-- <div slot="header">一段内容</div> -->
                <!-- 具名新式<template name="header"></template> -->
                <!-- 作用域插槽老式写法 -->
                <!-- <template slot-scoped="obj">{{obj}}</template> -->
                <!-- 作用域插槽新式写法，获取当前角色对象，row就是角色对象 -->
                <template #default="{ row: { id } }">
                  <el-button size="small" type="success" @click="handleOpenAssignDialog(id)">分配权限</el-button>
                  <el-button size="small" type="primary" @click="handleOpenEditDialog(id)">编辑</el-button>
                  <el-button
                    :disabled="$checkPermission('point=del')"
                    size="small"
                    type="danger"
                    @click="handleDel(id)"
                  >
                    删除
                  </el-button>
                </template>
              </el-table-column>
            </el-table>
            <!-- 分页器 -->
            <el-pagination
              :current-page="query.page"
              :page-sizes="[2, 3, 5, 10]"
              :page-size="query.pagesize"
              layout="total, sizes, prev, pager, next, jumper"
              :total="total"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
            ></el-pagination>
          </el-tab-pane>
          <el-tab-pane label="公司信息" name="company">
            <el-alert
              title="对公司名称、公司地址、营业执照、公司地区的更新，将使得公司资料被重新审核，请谨慎修改"
              type="info"
              show-icon
              :closable="false"
            />
            <!-- 表单 -->
            <el-form label-width="120px" style="margin-top: 50px">
              <el-form-item label="公司名称">
                <el-input v-model="companyForm.name" disabled style="width: 428px" />
              </el-form-item>
              <el-form-item label="公司地址">
                <el-input v-model="companyForm.companyAddress" disabled style="width: 50%" />
              </el-form-item>
              <el-form-item label="邮箱">
                <el-input v-model="companyForm.mailbox" disabled style="width: 50%" />
              </el-form-item>
              <el-form-item label="备注">
                <el-input v-model="companyForm.remarks" type="textarea" :rows="3" disabled style="width: 50%" />
              </el-form-item>
            </el-form>
          </el-tab-pane>
        </el-tabs>
      </el-card>
      <!-- 准备一个新增角色弹框 -->
      <el-dialog title="新增角色" :visible="showAddDialog" @close="handleAddDialogClose">
        <!-- 表单 -->
        <el-form ref="roleFormRef" :model="roleForm" :rules="roleFormRules" label-width="100px">
          <el-form-item label="角色名称" prop="name">
            <el-input v-model.trim="roleForm.name" placeholder="请输入角色名称" style="width: 90%" />
          </el-form-item>
          <el-form-item label="角色描述" prop="code">
            <el-input v-model.trim="roleForm.description" placeholder="请输入角色描述" style="width: 90%" />
          </el-form-item>
        </el-form>
        <template #footer>
          <el-button size="small" @click="handleAddDialogClose">取消</el-button>
          <el-button size="small" type="primary" style="margin-right: 50px" @click="handleAdd">确定</el-button>
        </template>
      </el-dialog>
      <!-- 编辑角色弹框 -->
      <el-dialog title="编辑角色" :visible="showEditDialog" @close="handleEditDialogClose">
        <!-- 表单 -->
        <el-form ref="roleFormRef" :model="roleForm" :rules="roleFormRules2" label-width="100px">
          <el-form-item label="角色名称" prop="name">
            <el-input v-model.trim="roleForm.name" placeholder="请输入角色名称" style="width: 90%" />
          </el-form-item>
          <el-form-item label="角色描述" prop="description">
            <el-input v-model.trim="roleForm.description" placeholder="请输入角色描述" style="width: 90%" />
          </el-form-item>
        </el-form>
        <template #footer>
          <el-button size="small" @close="handleEditDialogClose">取消</el-button>
          <el-button size="small" type="primary" style="margin-right: 50px" @click="handleEdit">确定</el-button>
        </template>
      </el-dialog>
      <!-- 分配权限弹框 -->
      <el-dialog title="分配权限" :visible="showAssignDialog" @close="handleAssignClose">
        <!--
          权限树形组件
          tree组件可以设置或获取tree组件中选中的节点，有两种方式
          1.通过 node(节点对象)方式
          2.通过 key 的方式，需要给tree添加node-key属性
          代码中：可以通过 this.$refs.treeRef 获取到tree组件对象，调用方法
            1.获取getCheckedNodes() / getCheckdeKeys()
            2.设置：setCheckedNodes([]) / setCheckedKeys([])
           -->
        <el-tree
          ref="treeRef"
          :data="permTreeData"
          node-key="id"
          :props="{ label: 'name' }"
          show-checkbox
          default-expand-all
          check-strictly
        />
        <template #footer>
          <el-button @click="handleAssignClose">取消</el-button>
          <el-button type="primary" @click="handleAssign">确定</el-button>
        </template>
      </el-dialog>
    </div>
  </div>
</template>
<script>
import {
  getRoleListAPI,
  delRoleAPI,
  addRoleAPI,
  getRoleDetailAPI,
  editRoleAPI,
  getCompanyDetailAPI,
  assignPermAPI
} from '@/api/settings'
import { getPermListAPI } from '@/api/permissions'
import { arr2Tree } from '@/utils/shift'
export default {
  name: 'SettingsView',
  data () {
    // 自定义校验名称函数
    const validateName = (rule, value, callback) => {
      // console.log('1-' + rule)
      // console.log('2-' + value)
      // console.log('3-' + callback)
      // rule: rules下的校验规则
      // value: 当前字段的值
      // callback: 回调函数，不通过传入new Error()参数；否则不传参
      // 用value的值去roleList数组做对比
      // some(): 检测数组中是否有满足条件的元素；若有返回true；否则返回false
      // 遍历数组，用每次拿到的部门对象名字和输入的名字比对
      const isSame = this.roleList.some(item => item.name === value)
      // 三元表达式
      isSame ? callback(new Error(`【${value}】已存在`)) : callback()
    }
    // 自定义校验名称函数
    const validateName2 = (rule, value, callback) => {
      // 在编辑的时候，部门名称无需要跟自己进行比较
      // 思路：从deptList中排除自己，然后再比较
      const isSame = this.deptList
        .filter(obj => obj.id !== this.item.id)// filter就是在排除自己
        .some(item => item.name === value)
      // 三元表达式
      isSame ? callback(new Error(`【${value}】部门已存在`)) : callback()
    }
    return {
      // 收集激活的tab栏
      activeName: 'role',
      // 数据总条数
      total: 0,
      // 角色列表
      roleList: [],
      // 获取角色列表查询参数
      query: {
        page: 1, // 页码
        pagesize: 5// 条数
      },
      // 控制新增角色弹框显示与隐藏
      showAddDialog: false,
      showEditDialog: false,
      // 角色表单
      roleForm: {
        name: '', // 角色名称
        description: '' // 角色描述
      },
      // 公司表单对象信息
      companyForm: {
        name: '',
        companyAddress: '',
        mailbox: '',
        remarks: ''

      },
      // 新增角色部门表单校验规则
      roleFormRules: {
        name: [
          { required: true, message: '角色名称不能为空', trigger: ['blur'] },
          { min: 1, max: 50, message: '长度在 1 到 50 个字符', trigger: ['blur'] },
          // 调用自定义校验函数
          { validator: validateName, trigger: 'blur' }
        ],
        description: [
          { required: true, message: '角色描述不能为空', trigger: ['blur'] },
          { min: 1, max: 50, message: '长度在 1 到 50 个字符', trigger: ['blur'] }
        ]
      },
      // 编辑角色部门表单校验规则
      roleFormRules2: {
        name: [
          { required: true, message: '角色名称不能为空', trigger: ['blur'] },
          { min: 1, max: 50, message: '长度在 1 到 50 个字符', trigger: ['blur'] },
          // 调用自定义校验函数
          { validator: validateName2, trigger: 'blur' }
        ],
        description: [
          { required: true, message: '角色描述不能为空', trigger: ['blur'] },
          { min: 1, max: 50, message: '长度在 1 到 50 个字符', trigger: ['blur'] }
        ]
      },
      // 控制分配权限弹框的显示
      showAssignDialog: false,
      // 权限树形数据
      permTreeData: []
    }
  },
  watch: {
    async activeName (newVal) {
      if (newVal === 'company') {
        if (this.companyForm.id) return
        // 发请求获取公司详情
        const resp = await getCompanyDetailAPI(this.$store.state.user.userInfo.companyId)
        // 做回显
        // console.log(resp)
        this.companyForm = resp.data
      }
    }
  },
  created () {
    this.getRoleList()
  },
  methods: {
    // 分配权限
    async handleAssign () {
      // 发起分配权限的请求:获取树形组件选中的节点（表明要给当前角色分配的权限）
      await assignPermAPI(this.roleId, this.$refs.treeRef.getCheckedKeys())
      // 关闭弹窗
      this.handleAssignClose()
      this.$message.success('分配角色权限成功')
    },
    // 分配权限弹框打开时
    async handleOpenAssignDialog (roleId) {
      // 保存当前员工id,给分配权限使用
      this.roleId = roleId
      // 显示弹框
      this.showAssignDialog = true
      // 请求权限列表数据
      const resp = await getPermListAPI()
      // console.log(resp.data)
      // 列表转为树形，数据再赋值
      this.permTreeData = arr2Tree(resp.data, '0')
      // console.log(this.permTreeData)
      //  请求角色详情
      const resp2 = await getRoleDetailAPI(roleId)
      // console.log(resp2)
      // 回显(让角色原有的权限选中，再来分配)
      // 把后台返回的权限id数组作为参数传递个CheckedKeys
      this.$refs.treeRef.setCheckedKeys(resp2.data.permIds)
    },
    // 分配权限弹框关闭时
    handleAssignClose () {
      this.showAssignDialog = false
      // 清空tree组件的选中状态
      this.$refs.treeRef.setCheckedKeys([])
    },
    async getRoleList () {
      const { data } = await getRoleListAPI(this.query)
      // console.log(data)
      const { total, rows } = data
      this.total = total
      this.roleList = rows
    },
    // 处理每页的条数变化
    handleSizeChange (val) {
      // 把选择的条数同步到querysize中
      // console.log(`每页 ${val} 条`)
      this.query.pagesize = val
      this.getRoleList()
    },
    // 处理总共多少页的页码变化
    handleCurrentChange (val) {
      // console.log(`当前页: ${val}`)
      // 把选择的页码同步到query中
      this.query.page = val
      this.getRoleList()
    },
    // 自定义序号列下标
    handleIndex (index) {
      // 规律：当前数据的序号 + 每页条数 * （当前页码 - 1）
      return (index + 1) + this.query.pagesize * (this.query.page - 1)
    },
    // 删除角色
    async handleDel (roleId) {
      // console.log(roleId)
      // 询问
      try {
        // 1.询问
        await this.$confirm('此操作不可逆，确定删除吗？', '温馨提示', {
          type: 'warning',
          cancelButtonText: '取消',
          confirmButtonText: '确定'
        })
        // 2.确定
        //    2.1 发请求(通知后台，从数据库中删除)
        await delRoleAPI(roleId)
        // 如果当前页面大于1，并且roleList中只有一条数据，
        // 需要获取上一页的数据
        if (this.query.page > 1 && this.roleList.length === 1) {
          // 页面自减
          this.query.page--
        }
        //    2.2 重新获取角色列表
        this.getRoleList()
        //    2.3 给个删除成功的提示
        this.$message({
          message: '删除成功！',
          center: true
        })
      } catch (error) {
        // 3.取消
      }
    },
    // 关闭新增角色弹窗
    handleAddDialogClose () {
      this.showAddDialog = false
      // 重置表单
      // this.$refs.roleFormRef.resetFields()
      // 遍历roleForm对象，把每个字段清空
      Object.keys(this.roleForm).forEach(key => {
        this.roleForm[key] = ''
      })
    },
    // 新增角色校验
    async handleAdd () {
      // 整体校验
      // 发起新增请求
      const resp = await addRoleAPI(this.roleForm)
      console.log(resp)
      // 关闭弹框
      this.handleAddDialogClose()
      // 获取角色列表
      this.getRoleList()
    },
    // 编辑角色弹框打开时
    async handleOpenEditDialog (roleId) {
      this.showEditDialog = true
      // 根据roleId获取角色详情做回显
      const resp = await getRoleDetailAPI(roleId)
      // console.log(resp)
      // 把后台返回的resp.data数据直接赋值给roleForm(因为属性名一样才能整体直接赋值)
      this.roleForm = resp.data
      // console.log(this.roleForm)
    },
    // 关闭编辑角色弹框
    handleEditDialogClose () {
      this.showEditDialog = false
    },
    // 编辑角色
    async handleEdit () {
      // 整体校验
      // 发起编辑请求
      await editRoleAPI(this.roleForm)
      // 关闭
      this.handleEditDialogClose()
      // 获取角色列表
      this.getRoleList()
    }
  }
}
</script>

<style lang="scss" scoped>
.el-pagination {
  margin-top: 10px;
  transform: translateX(25%);
}
</style>
